using System;
using System.Diagnostics;
using System.Drawing;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Windows.Forms;
using System.Windows.Forms.Design;

//using ICSharpCode.Core.AddIns;
//using ICSharpCode.Core.Services;

namespace FormDesigner
{
	public class MenuCommandService : IMenuCommandService
	{
		public IDesignerHost host;
		ArrayList     commands = new ArrayList();
		ArrayList     verbs    = new ArrayList();
		PopupMenuManager popupMenuManager = new PopupMenuManager();
		
		public DesignerVerbCollection Verbs 
		{
			get 
			{
				DesignerVerbCollection verbCollection = CreateDesignerVerbCollection();
				verbCollection.AddRange((DesignerVerb[])verbs.ToArray(typeof(DesignerVerb)));
				return verbCollection;
			}
		}
		
		public MenuCommandService(IDesignerHost host)
		{
			this.host = host;
		}
		
		public void AddCommand(MenuCommand command)
		{
			Debug.Assert(command != null);
			Debug.Assert(command.CommandID != null);
			Debug.Assert(!commands.Contains(command));
			this.commands.Add(command);
		}
		
		public void AddVerb(DesignerVerb verb)
		{
			Debug.Assert(verb != null);
			this.verbs.Add(verb);
		}
		
		public void RemoveCommand(MenuCommand command)
		{
			Debug.Assert(command != null);
			commands.Remove(command.CommandID);
		}
		
		public void RemoveVerb(DesignerVerb verb)
		{
			Debug.Assert(verb != null);
			verbs.Remove(verb);
		}
		
		public bool GlobalInvoke(CommandID commandID)
		{
			MenuCommand menuCommand = FindCommand(commandID);
			if (menuCommand == null) 
			{
				MessageBox.Show("Can't find command " + commandID, "Error");
				return false;
			}
			
			IMessageFilter aFormKeyHandler = (IMessageFilter)this.host.GetService(typeof(IMessageFilter));
			if(aFormKeyHandler != null) Application.RemoveMessageFilter(aFormKeyHandler);

			menuCommand.Invoke();
			if(aFormKeyHandler != null) Application.AddMessageFilter(aFormKeyHandler);
			return true;
		}
		
		public MenuCommand FindCommand(CommandID commandID)
		{
			//			if (StringType.StrCmp(MenuUtilities.GetCommandNameFromCommandID(commandID), "", false) == 0 && StringType.StrCmp(commandID.ToString(), "74d21313-2aee-11d1-8bfb-00a0c90f26f7 : 12288", false) == 0) {
			//				return MenuUtilities.gPropertyGridResetCommand;
			//			}
			foreach (MenuCommand menuCommand in commands) 
			{
				if (menuCommand.CommandID == commandID) 
				{
					return menuCommand;
				}
			}
			
			foreach (DesignerVerb verb in Verbs) 
			{
				if (verb.CommandID.Guid == commandID.Guid && verb.CommandID.ID == commandID.ID) 
				{
					return verb;
				}
			}
			return null;
		}
		
		public void ShowContextMenu(CommandID menuID, int x, int y)
		{
			/*string contextMenuPath = "/SharpDevelop/FormsDesigner/ContextMenus/";
			
			if (menuID == MenuCommands.ComponentTrayMenu) 
			{
				contextMenuPath += "ComponentTrayMenu";
			} 
			else if (menuID == MenuCommands.ContainerMenu) 
			{
				contextMenuPath += "ContainerMenu";
			} 
			else if (menuID == MenuCommands.SelectionMenu) 
			{
				contextMenuPath += "SelectionMenu";
			} 
			else if (menuID == MenuCommands.TraySelectionMenu) 
			{
				contextMenuPath += "TraySelectionMenu";
			} 
			else 
			{
				throw new Exception();
			}*/
			
			popupMenuManager.ShowPopupMenu(this, menuID, x, y);
			//ICSharpCode.Core.AddIns.Codons.PopupMenuManager.ShowPopupMenu(this, contextMenuPath, x, y);
		}
		
		public DesignerVerbCollection CreateDesignerVerbCollection()
		{
			DesignerVerbCollection designerVerbCollection = new DesignerVerbCollection();
			
			ISelectionService selectionService = (ISelectionService)host.GetService(typeof(ISelectionService));
			if (selectionService != null && selectionService.SelectionCount == 1) 
			{
				IComponent selectedComponent = selectionService.PrimarySelection as Component;
				if (selectedComponent != null) 
				{
					IDesigner designer = host.GetDesigner((IComponent)selectedComponent);
					if (designer != null) 
					{
						designerVerbCollection.AddRange(designer.Verbs);
					}
				}
				
				if (selectedComponent == host.RootComponent) 
				{
					designerVerbCollection.AddRange((DesignerVerb[])this.verbs.ToArray(typeof(DesignerVerb)));
				}
			}
			return designerVerbCollection;
		}
	}
}